// Dart 有两种传参方法：位置参数和命名参数

int sumUp(int a, int b, int c) {
  return a + b + c;
}

int total = sumUp(1, 2, 3);

// 将这些参数包裹在方括号中，使其变成可选位置参数：
int sumUpToFive(int a, [int? b, int? c, int? d, int? e]) {
  int sum = a;
  if (b != null) sum += b;
  if (c != null) sum += c;
  if (d != null) sum += d;
  if (e != null) sum += e;
  return sum;
}

int total2 = sumUpToFive(1, 2);
int otherTotal = sumUpToFive(1, 2, 3, 4, 5);

// 可选位置参数永远放在方法参数列表的最后。除非你给它们提供一个默认值，否则默认为 null:
int sumUpToFive3(int a, [int b = 2, int c = 3, int d = 4, int e = 5]) {
  return a + b + c + d + e;
}

int newTotal = sumUpToFive3(1);

String joinWithCommas(int a, [int? b, int? c, int? d, int? e]) {
  String sum = a.toString();
  if (b != null) sum += ',' + b.toString();
  if (c != null) sum += ',' + c.toString();
  if (d != null) sum += ',' + d.toString();
  if (e != null) sum += ',' + e.toString();
  return sum;
}

// 你可以使用大括号语法定义可选命名参数。
// 一个方法不能同时使用可选位置参数和可选命名参数。
void printName(String firstName, String lastName, {String? suffix}) {
  print('$firstName $lastName ${suffix ?? ''}');
}
// 如果一个参数的类型是非空的，那么你必须要提供一个默认值
// void printName(String firstName, String lastName, {String suffix = ''}) {
//   print('$firstName $lastName $suffix');
// }

// copyWith 方法应该根据当前实例返回一个新的 MyDataObject 并将前面参数（如果有的话）的数据复制到对象的属性中
class MyDataObject {
  final int anInt;
  final String aString;
  final double aDouble;

  MyDataObject({
    this.anInt = 1,
    this.aString = 'Old!',
    this.aDouble = 2.0,
  });
  MyDataObject copyWith({int? newInt, String? newString, double? newDouble}) {
    var newObj = MyDataObject(
        anInt: newInt ?? this.anInt,
        aString: newString ?? this.aString,
        aDouble: newDouble ?? this.aDouble);
    return newObj;
  }
}

main(List<String> args) {
  printName('Avinash', 'Gupta');
  printName('Poshmeister', 'Moneybuckets', suffix: 'IV');
}
